#!/bin/sh -f
# $Id$
# Copyright (c) 2012 Prabhu Gurumurthy <pgurumur@gmail.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# __version__  = "$Revision$"
# __author__   = "$Author$"
# __modified__ = "$Date$"

PROG=`basename $0`
HG=`which hg`
uid=`id -u`
UNAME=`uname`
STAT=`which stat`
PWD=`pwd`
DIRUID=
AWK=`which awk`
NEW=0
ECHO=
FTYPE=
STATUS=

if [ ${UNAME} = "Linux" ]; then
   ECHO="echo -e"
elif [ ${UNAME} = "Darwin" ]; then
   ECHO="echo -e"
elif [ ${UNAME} = "OpenBSD" ]; then
   ECHO="echo"
fi

# A simple usage function, because there are no paramters to be handled by this
# script
usage () {
   cprint "Automatic add/checkin into mercurial when opening/editing a file"
   echo "usage: ${PROG} file(s)"
   exit 1
}

# Echo error along with the script name and exit
err () {
   echo "${PROG}: " $*
   exit 1
}

cprint () {
   ${ECHO} "\033[33m$1\033[0m"
}

# Print the status of the file in mercurial, make sure to set the NEW flag to
# be zero at the start of the function and only toggle it if the file does not
# exist in the repository and added if loop for the "?" flag
status () {
   if [ ! -z $1 ]; then
      NEW=0
      STATUS=`${HG} status $1 | ${AWK} '{ print $1 }'`
      # If status var is present and length is not zero
      if [ ! -z ${STATUS} ]; then
         test ${STATUS} = "M" && cprint "$1 has been modified"
         test ${STATUS} = "A" && cprint "$1 has been added to the repository"
         if [ ${STATUS} = "?" ]; then
            NEW=1
            cprint "$1 does not exist in the repository"
         fi
      fi
   fi
}

# Commit the file to the repository, this does not mean the file is pushed into
# the main repository yet
commit () {
   if [ ! -z $1 ]; then
      if [ ! -z ${STATUS} ]; then
         echo "Enter comments for $1 "
         echo -n ">> "
         read comment
         ${HG} commit -m "${comment}" $1
         ${HG} par $1
      else
         cprint "Nothing changed, so not committing the file: $1"
      fi
   fi
}

# Add the file, similar to the commit option, self explanatory
add () {
   if [ ! -z $1 ]; then
      ${HG} add $1
      status $1
   fi
}

# Signal handle to interrupt the program, again self explantory
sighandle () {
   ${ECHO} "\033[31muh oh! I am getting killed\033[0m"
   exit 1
}

# Get File type using stat function
# Doesn't return just uses global variables
getftype () {
   if [ ${UNAME} = "Linux" ]; then
      FTYPE=`${STAT} -c "%F" $1 | ${AWK} '{ print tolower($0) }'`
   elif [ ${UNAME} = "Darwin" ]; then
      FTYPE=`${STAT} -f "%HT" $1 | ${AWK} '{ print tolower($0) }'`
   elif [ ${UNAME} = "OpenBSD" ]; then
      FTYPE=`${STAT} -f "%HT" $1 | ${AWK} '{ print tolower($0) }'`
   fi
}


# Verify whether we have files from the command line
NF=`echo $* | ${AWK} "{ print NF }"`

# Set up the trap handle
trap sighandle 15 2 18

# execute usage if there are no files given in the command line
test ${NF} -eq 0 && usage

# Check the directory permissions with the userid to see whether the user
# has the privilege to store the fole
test ${UNAME} = "Linux" && DIRUID=`${STAT} -c "%u" ${PWD}`
test ${UNAME} = "OpenBSD" && DIRUID=`${STAT} -f "%u" ${PWD}`
test ${UNAME} = "Darwin" && DIRUID=`${STAT} -f "%u" ${PWD}`
test ${DIRUID} -eq ${uid} || err "${PWD} isn't owned by used with uid: ${uid}"

# For each file in the command line do the following
# 1. Edit the file using vim
# 2. Check the status of the file
#     a. If the file is new, then add it
#     b. If the file is present in the repo, then commit it
for file in $*; do
   ${STAT} ${file} > /dev/null 2>&1
   if [ $? -ne 0 ]; then
      vim ${file}
      add ${file}
   else
      getftype ${file}
      if [ "${FTYPE}" = "regular file" ]; then
         vim ${file}
         status ${file}
         if [ ${NEW} -eq 1 ]; then
            add ${file}
         else
            commit ${file}
         fi
         NEW=0
      else
         cprint "${file} is not a file, it is a ${FTYPE}"
      fi
   fi
done
